﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using System.Xml.Linq;

using Perseus;
using Perseus.Xml;

namespace Hetymine.Executioner.Commands {
    public class HotKey : HotKeyInfo, ICloneable {
        public HotKey() {
            this.Commands = new List<CommandInfo>();
            this.Key = Key.None;
            this.Modifiers = ModifierKeys.None;
            this.KeyValue = string.Empty;
        }

        public void Load(XElement element) {
            this.KeyValue = element.Element("Key").Value;
            this.Key = PInput.ResolveKey(this.KeyValue);

            string[] mods = element.Element("Modifiers").ValueOrEmpty().Split(
                "+",
                SplitOptions.Trim | SplitOptions.RemoveEmptyEntries
            );
            this.Modifiers = ModifierKeys.None;
            foreach (string m in mods) {
                if (m.ToLower() == "alt") {
                    this.Modifiers |= ModifierKeys.Alt;
                    continue;
                }
                if (m.ToLower() == "ctrl") {
                    this.Modifiers |= ModifierKeys.Control;
                    continue;
                }
                if (m.ToLower() == "shift") {
                    this.Modifiers |= ModifierKeys.Shift;
                    continue;
                }
            }

            this.Commands = Helper.Commands(element);
        }
        public XElement Save() {
            if (this.IsEmpty) {
                throw new Exception("Cannot save empty hot key.");
            }

            XElement xe = new XElement("HotKey");
            xe.Add(new XElement("Key", this.KeyValue));

            string mod = string.Empty;
            if ((this.Modifiers | ModifierKeys.Control) == this.Modifiers) {
                mod += "Ctrl + ";
            }

            if ((this.Modifiers | ModifierKeys.Shift) == this.Modifiers) {
                mod += "Shift + ";
            }

            if ((this.Modifiers | ModifierKeys.Alt) == this.Modifiers) {
                mod += "Alt + ";
            }
            if (mod != string.Empty) {
                mod = mod.Substring(0, mod.Length - 3);
                xe.Add(new XElement("Modifiers", mod));
            }

            foreach (CommandInfo ci in this.Commands) {
                XElement cmd = new XElement("Command", ci.Command);
                if (ci.Arguments != string.Empty) {
                    cmd.Add(new XAttribute("Args", ci.Arguments));
                }
                xe.Add(cmd);
            }

            return xe;
        }

        public List<CommandInfo> Commands { get; set; }

        public string KeyValue { get; set; }
        
        public bool IsEmpty {
            get { return (this.Key == Key.None); }
        }

        public override string ToString() {
            string s = string.Empty;

            if ((this.Modifiers | ModifierKeys.Control) == this.Modifiers) {
                s += "Ctrl + ";
            }

            if ((this.Modifiers | ModifierKeys.Shift) == this.Modifiers) {
                s += "Shift + ";
            }

            if ((this.Modifiers | ModifierKeys.Alt) == this.Modifiers) {
                s += "Alt + ";
            }

            s += this.KeyValue;

            return s;
        }

        public void ExecuteCommand() {
            foreach (CommandInfo c in this.Commands) {
                Executioner.ExecuteProcessCommand(c.Command, c.Arguments);                
            }
        }
        
        public object Clone() {
            HotKey hk = (HotKey)this.MemberwiseClone();
   
            hk.Commands = new List<CommandInfo>();
            foreach (CommandInfo ci in this.Commands) {
                hk.Commands.Add(new CommandInfo(ci.Command, ci.Arguments));
            }

            return hk;
        }
    }
}
